﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using DeepZoomPivotConstructor.VisualLib;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RenderEngineInterfaces;
using SimpleHTMLRender;

namespace t_SimpleHTMLRender
{
    /// <summary>
    /// Test out rendering a simple HTML file.
    /// </summary>
    [TestClass]
    public class t_HTMLRender
    {
        public t_HTMLRender()
        {
        }

        [TestInitialize]
        public void InitForTest()
        {
            t_TestingLibrary.Utilities.MyClassInit();
        }

        [TestCleanup]
        public void ShutDownTest()
        {
            t_TestingLibrary.Utilities.MyClassDone();
        }

        [TestMethod]
        public void TestCTor()
        {
            var h = new HTMLRender();
        }

        [TestMethod]
        public void TestHTMLRenderOK()
        {
            var h = new HTMLRender();

            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, h.RenderPriority(null), "Failed to deal with null correctly");
            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, h.RenderPriority(DateTime.Now), "Failed to correctly deal with a rendering a datetime!");
            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, h.RenderPriority(new FileInfo("C:\\bogus")), "bad website shouldn't be rendered");
            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, h.RenderPriority(new FileInfo("c:\\bogus.txt")), "bad txt file shouldn't be rendered");
            Assert.AreEqual(RenderPluginPriority.RPPGeneric, h.RenderPriority(new FileInfo("c:\\HEPAPAgendaOct2009.shtml")), "shtml can be rendered!");
            Assert.AreEqual(RenderPluginPriority.RPPGeneric, h.RenderPriority(new FileInfo("c:\\HEPAPAgendaOct2009.html")), "html can be rendered!");
            Assert.AreEqual(RenderPluginPriority.RPPGeneric, h.RenderPriority(new FileInfo("c:\\HEPAPAgendaOct2009.htm")), "htm can be rendered!");
        }

        [Export(typeof(IRenderEngine))]
        class DummyRenderEngine : IRenderEngine
        {
            public System.Threading.Tasks.Task<DeepZoomPivotConstructor.VisualLib.Visual> RenderToFuture(object what, Type[] disallowRenderPlugins = null, bool forceAsComposableUnit = false, bool asComposableUnitIfNoneWithin = false)
            {
                Trace.WriteLine("Rendering " + what.ToString());
                return System.Threading.Tasks.Task<DeepZoomPivotConstructor.VisualLib.Visual>.Factory.StartNew(() =>
                    {
                        var r = new VisualBitmapImage(1.0, 1.0, 100, Color.Blue);
                        if (forceAsComposableUnit)
                        {
                            r.SetAsComposableUnit(null);
                        }
                        return r;
                    });
            }

            public DeepZoomPivotConstructor.VisualLib.Visual Render(object what, Type[] disallowRenderPlugins = null, bool forceAsComposableUnit = false, bool asComposableUnitIfNoneWithin = false)
            {
                return RenderToFuture(what, disallowRenderPlugins, forceAsComposableUnit).Result;
            }
        }

        [Export(typeof(IRenderEngine))]
        class DummyRenderEngineSomeNulls : IRenderEngine
        {
            int count = 0;
            public System.Threading.Tasks.Task<DeepZoomPivotConstructor.VisualLib.Visual> RenderToFuture(object what, Type[] disallowRenderPlugins = null, bool forceAsComposableUnit = false, bool asComposableUnitIfNoneWithin = false)
            {
                Trace.WriteLine("Rendering " + what.ToString());
                return System.Threading.Tasks.Task<DeepZoomPivotConstructor.VisualLib.Visual>.Factory.StartNew(() =>
                {
                    count++;
                    if (count % 2 == 0)
                    {
                        return null;
                    }
                    else
                    {
                        return new VisualBitmapImage(1.0, 1.0, 100, Color.Blue);
                    }
                });
            }

            public DeepZoomPivotConstructor.VisualLib.Visual Render(object what, Type[] disallowRenderPlugins = null, bool forceAsComposableUnit = false, bool asComposableUnitIfNoneWithin = false)
            {
                return RenderToFuture(what, disallowRenderPlugins, forceAsComposableUnit).Result;
            }
        }

        [Export(typeof(ILayoutHelper))]
        class DummyLayoutHelper : ILayoutHelper
        {
            public Visual LayoutIn2By3Rows(IEnumerable<Visual> visuals)
            {
                VisualHolder h = new VisualHolder();
                foreach (var item in visuals)
                {
                    h.AddImage(item);
                }
                return h;
            }
        }

        [TestMethod]
        [DeploymentItem("doe.html")]
        public void TestRenderDOESite()
        {
            TestDOEHTML("doe.html");
        }

        private static void TestDOEHTML(string uri)
        {
            FileInfo sourceFile = new FileInfo(uri);
            Assert.IsTrue(sourceFile.Exists, "Test file not here!");
            t_TestingLibrary.Utilities.AddPart(new DummyRenderEngine());
            t_TestingLibrary.Utilities.AddPart(new DummyLayoutHelper());
            var h = new HTMLRender();
            t_TestingLibrary.Utilities.Compose(h);

            var result = h.Render(sourceFile);
            var r = result.Result;
            /// 12 talks, 1 slide for the talk, one slide for the background, and then one total background.
            Assert.AreEqual(12 * 2 + 1, r.SGNodeList.Count, "Incorrect number of talks rendered!");
            Assert.IsTrue(r.Info.Title.Contains("The Office of High Energy Physics"), "Title of the rendering isn't correct: " + r.Info.Title);
            Assert.IsTrue(r.Info.Title.Contains("-"), "Title of the rendering isn't correct: " + r.Info.Title + " (no date?)");
            Assert.IsNotNull(r.Info.Info[0], "The date isn't set");

            var talks = r.GetHierarchicalEnumerator(v => v.Info != null && !v.Info.Title.Contains("Office of High")).Where(v => v.Info != null);
            foreach (var t in talks)
            {
                Trace.WriteLine("Talk title: '" + t.Info.Title + "'");
            }

            var taslkWithTitle = talks.Where(v => v.Info.Title == "Status of LHC detectors");
            Assert.AreEqual(1, taslkWithTitle.Count(), "No talk with correct title!");

            var cmt = r.GetHierarchicalEnumerator(v => v.IsCompositionUnit);
            Assert.AreEqual(12, cmt.Where(t => t.IsCompositionUnit).Count(), "Bad number of composable units!");
        }

        [TestMethod]
        [DeploymentItem("doe.html")]
        public void TestSomeNullRendersBack()
        {
            FileInfo sourceFile = new FileInfo("doe.html");
            Assert.IsTrue(sourceFile.Exists, "Test file not here!");
            t_TestingLibrary.Utilities.AddPart(new DummyRenderEngineSomeNulls());
            t_TestingLibrary.Utilities.AddPart(new DummyLayoutHelper());
            var h = new HTMLRender();
            t_TestingLibrary.Utilities.Compose(h);

            var result = h.Render(sourceFile);
            var r = result.Result;
        }
    }
}
